package ca.etsmtl.log430.common;

import java.text.SimpleDateFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;


/**
 * This class defines the Resource object for the system. Besides the basic
 * attributes, there are two lists maintained. alreadyAssignedProjectList is a
 * ProjectList object that maintains a list of projects that the resource was
 * already assigned to prior to this execution of the system.
 * projectsAssignedList is also a ProjectList object that maintains a list of
 * projects assigned to the resource during the current execution or session.
 * 
 * @author A.J. Lattanze, CMU
 * @version 1.6, 2013-Oct-06
 */

/* Modification Log
 ****************************************************************************
 * 
 * v1.6, R. Champagne, 2013-Oct-06 - Various refactorings for new lab.
 * 
 * v1.5, R. Champagne, 2012-Jun-19 - Various refactorings for new lab.
 * 
 * v1.4, R. Champagne, 2012-May-31 - Various refactorings for new lab.
 * 
 * v1.3, R. Champagne, 2012-Feb-02 - Various refactorings for new lab.
 * 
 * v1.2, 2011-Feb-02, R. Champagne - Various refactorings, javadoc comments.
 *  
 * v1.1, 2002-May-21, R. Champagne - Adapted for use at ETS. 
 * 
 * v1.0, 12/29/99, A.J. Lattanze - Original version.

 ****************************************************************************/

public class Resource {

	/**
	 * Resource's last name
	 */
	private String lastName;
	
	/**
	 * Resource's first name
	 */
	private String firstName;
	
	/**
	 * Resource's identification number
	 */
	private String id;
	
	/**
	 * Resource role 
	 */
	private String role;

	/**
	 *  List of projects the resource is already allocated to
	 */
	private ProjectList alreadyAssignedProjectList = new ProjectList();

	/**
	 *  List of projects assigned to the resource in this session
	 */
	private ProjectList projectsAssignedList = new ProjectList();

	/**
	 * Assigns a project to a resource.
	 * 
	 * @param project
	 */
	public void assignProject(Project project) {

		getProjectsAssigned().addProject(project);

	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getFirstName() {
		return firstName;
	}

	public void setID(String id) {
		this.id = id;
	}

	public String getID() {
		return id;
	}

	public void setRole(String role) {
		this.role = role;
	}

	public String getRole() {
		return role;
	}

	public void setPreviouslyAssignedProjectList(ProjectList projectList) {
		this.alreadyAssignedProjectList = projectList;
	}

	public ProjectList getPreviouslyAssignedProjectList() {
		return alreadyAssignedProjectList;
	}

	public void setProjectsAssigned(ProjectList projectList) {
		this.projectsAssignedList = projectList;
	}

	public ProjectList getProjectsAssigned() {
		return projectsAssignedList;
	}
	
public String isOverloaded(Project projectToAdd, ProjectList projects){
		
		boolean done = false;
		
		String result = "";
		Project project = null;
		Project current = null;
		ArrayList<Project> projectsAssigned = new ArrayList<Project>();
		
		int currentChargeLevel = 0;
		int nextChargeLevel = 0;
			
		//permet de formater les dates
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		
		//Sert aux dates du projet actuel dans la liste
		Date projectStartDate = null;
		Date projectEndDate = null;
		
		//Sert aux dates du nouveau projet auquel on veut assigné la ressource
		Date projectToAddStartDate = null;
		Date projectToAddEndDate = null;
		
		/*
		 * Si currentList vaut 1 , on est dans la liste des projets déjà assignés.
		 * Si currentList vaut 2 , on est dans la liste de projetsassignés durant l'éxécution.
		 */
		int currentList = 1;
		
		//Mettre le pointeur au début de la liste 
		getPreviouslyAssignedProjectList().goToFrontOfList();
		
		//Obtenir les projets déjà assignés
		while (!done) {
			if(currentList == 1){
				project = getPreviouslyAssignedProjectList().getNextProject();
			}else{
				project = getProjectsAssigned().getNextProject();
			}
			

			if(project == null && currentList == 1){
				/*
				 * Si on a fini de parcourir la premiere liste, on passe à la seconde
				 * Placer le pointeur au début de la liste de projets assignés
				 */
				getProjectsAssigned().goToFrontOfList();
				currentList = 2;
			}else if(project == null && currentList == 2){
				/*
				 *  On a fini de parcourir la seconde list
				 */
				done = true;
			}else{
				
				/*
				 * On assigne le projet à une varible, on ajoute ses informations 
				 * dans une liste et on incrémente le niveau de charge de la ressource 
				  */
				current = projects.findProjectByID(project.getID());
				projectsAssigned.add(current);
			}
		}
		
		done = false;
		
		
		/*
		 * Sert à comparer les dates des projets déjà assignés à la ressource
		 * avec le nouveau projet auquel on veut l'assigné.
		*/
		for(Project prj : projectsAssigned){ //Pour chaque projet dans la liste
			try {
				if(done == false){
					/*
					 * Obtenir le niveau de charge, si jamais 
					 * on assignait la ressource au nouveau projet.
					 */
					nextChargeLevel = prj.getNumericPriority()+ projectToAdd.getNumericPriority();

					if(projectToAddStartDate == null && projectToAddEndDate == null){
						/*
						 * Si on à pas encore initialiser les dates du nouveau projet,
						 * on les formate  pour faire des comparaisons plutard
						 */
						projectToAddStartDate = sdf.parse(projectToAdd.getStartDate());
						projectToAddEndDate = sdf.parse(projectToAdd.getEndDate());
					}
					
					/*
					 * On formatte les dates du projet actuel pour 
					 * pouvoir faire les comparaisons plutard
					 */
					projectStartDate = sdf.parse(prj.getStartDate());
					projectEndDate = sdf.parse(prj.getEndDate());
					
					 
					if(projectToAddStartDate.after(projectEndDate)){
						/*
						 * Verifier si le nouveau projet debute à la fin du projet actuel
						 */
						result = "true";
						
					}else if(projectToAddStartDate.after(projectStartDate)){
						/*
						 * si le nouveau projet debute apres la 
						 * date de commencement du projet déjà assigné
						 */
						if(projectToAddEndDate.before(projectEndDate) || 
							projectToAddEndDate.after(projectEndDate)){  
							/* 
							 * si le nouveau projet fini avant ou apres 
							 * la date de fin d'un projet déjà assigné
							 */
						
							/*
							 * Si le nouveau niveau de charge serait 
							 * plus élevé en assignant le projet, il y a erreur
							 */
							if(nextChargeLevel > 100){
								result = "Error !! Resource is overloaded at 100%";
								done = true;
							}else{
								result = "true";
							}
						}
					}else if(projectToAddStartDate.before(projectStartDate)){
							/*
							 * si le nouveau projet débute avant un projet déjà assignée
							 */
						if(	projectToAddEndDate.before(projectEndDate) || 
							projectToAddEndDate.after(projectEndDate)){
							/*
							 * si le nouveau projet termine avant 
							 * ou  apres un projet déjà assigné 
							 */							
							if(nextChargeLevel > 100){
								/*
								 * Si le nouveau niveau de charge serait plus
								 *  élevé en assignant le projet, il y a erreur
								 */
								result = "Error !! Resource is overloaded at 100%";
								done = true;
							}else{
								result = "true";
							}
						}
						
					}else if(projectToAddStartDate.equals(projectStartDate)){
						/*
						 * si le nouveau projet débute le même jour
						 */
						
						if(nextChargeLevel > 100){
							/*
							 * Si le nouveau niveau de charge serait plus 
							 * élevé en assignant le projet, il y a erreur.
							 */
							result = "Error !! Resource is overloaded at 100%";
							done = true;
						}else{
							result = "true";
						}
					}
				}
			} catch (ParseException e) {
				e.printStackTrace();
			}	
		}
		// on retourne le résultat
		return result;
	}

} // Resource class